package com.ff.xyh.service.userfront.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ff.xyh.common.entity.result.ResultMessage;
import com.ff.xyh.common.entity.result.ResultObject;
import com.ff.xyh.common.servicebase.exception.MyException;
import com.ff.xyh.common.utils.*;
import com.ff.xyh.common.entity.userfront.FrontUser;
import com.ff.xyh.common.entity.userfront.UserRestricted;
import com.ff.xyh.service.userfront.mapper.FrontUserMapper;
import com.ff.xyh.service.userfront.service.FrontUserService;
import com.ff.xyh.service.userfront.service.UserRestrictedService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * <p>
 * 前端用户表 服务实现类
 * </p>
 *
 * @author ff
 * @since 2022-10-25
 */
@Service
public class FrontUserServiceImpl extends ServiceImpl<FrontUserMapper, FrontUser> implements FrontUserService {

    @Autowired
    private UserRestrictedService userRestrictedService;

    //登录的方法
    @Override
    public FrontUser login(String userToken, String password) {
        //非空判断
        if(StringUtils.isEmpty(userToken) || StringUtils.isEmpty(password)) {
            throw new MyException(20001,"用户名或邮箱或密码为空，登录失败");
        }
        QueryWrapper<FrontUser> wrapper = new QueryWrapper<>();
        // 若包含 . 则为邮箱登录 若 userToken 为纯数字 则是手机号登录 若为数字加字母 则为用户名登录
        if (userToken.contains("."))
            wrapper.eq("email",userToken);
        // 不包含 . 符合手机号正则匹配 为手机号登录
        else if (CommonUtil.isPhoneNumber(userToken))
            wrapper.eq("phone",userToken);
        // 不包含 . 也不是纯数字 则为用户名登录
        else if (!StringUtils.isNumeric(userToken))
            wrapper.eq("username",userToken);
        else
            throw new MyException(20001,"请求参数有误");

        FrontUser currentUser = baseMapper.selectOne(wrapper);

        if (currentUser == null) {
            throw new MyException(20001,"没有找到该用户");
        }

        //判断密码
        //因为存储到数据库密码用MD5加密的
        //所以把输入的密码进行MD5加密，再和数据库密码进行比较
        if(! MD5.encrypt(password).equals(currentUser.getPassword())) {
            throw new MyException(20001,"密码错误");
        }

        //判断用户是否异常 异常则需要查看是否封号
        if(currentUser.getStatus()!=0) {
            UserRestricted userRestricted = userRestrictedService.getUserRestrictedByFrontUserId(currentUser.getId());
            if (userRestricted == null )
                throw new MyException(20001,"账号未知异常");
            else if (userRestricted.getStatus() == -1)
                throw new MyException(20001,"账号已注销");
            else if (userRestricted.getStatus() == 0)
                throw new MyException(20001,"账号被永久封号");
            else if (userRestricted.getStatus() > 3)
                throw new MyException(20001,"账号封号次数已超过三次，禁止使用");
            else if (userRestricted.getGmtEffective().getTime() > System.currentTimeMillis())
                throw new MyException(20002,"账号因 \"" + userRestricted.getStatement() + "\" 被封号至"
                        + DateTimeUtil.stampToTime(userRestricted.getGmtEffective().getTime()));
            else {
                // 异常信息已过期 账号已解封 更新账号信息 删除封号信息
                currentUser.setStatus(0);
                if (! (baseMapper.updateById(currentUser) > 0))
                    throw new MyException(20001, "用户解封失败");
                else if ( ! // ! 表示不成功 else if 表示需要前面用户解封成功才能继续删除封号信息
                            (
                                userRestrictedService.updateUserRestricted(
                                        userRestricted.setStatement("封号时间已过，自动解封"))
                                &&
                                userRestrictedService.remove(
                                        new QueryWrapper<UserRestricted>()
                                                .eq("user_id", userRestricted.getUserId())
                                )
                            )
                    )
                    throw new MyException(20001, "用户解封成功，但解封信息修改出错");
            }
        }
        //登录成功
        //生成token字符串，使用jwt工具类
        return currentUser;
    }

    @Override
    public String createTokenWithUserId(String id) {
        return JwtUtils.createJwtTokenWithUserId(id);
    }

    @Override
    public boolean updateUserPasswordWithUserId(String id, String password) {
        FrontUser frontUser = baseMapper.selectById(id);
        // 对象存在
        if (frontUser != null) {
            frontUser.setPassword(MD5.encrypt(password));
            if (baseMapper.updateById(frontUser) > 0)
                return true;
            else
                return false;
        } else {
            return false;
        }
    }

    @Override
    public FrontUser updateUserLastLog(String id) {
        FrontUser frontUser = this.getById(id);
        if (frontUser == null)
            return null;

        Date lastlog = frontUser.getGmtLastlog();

        frontUser.setGmtLastlog(new Date());
        // 修改失败则将最后登录时间设置回去后返回 这样返回空表示用户不存在
        if (! this.updateById(frontUser)) {
            frontUser.setGmtLastlog(lastlog);
        }
        return frontUser;

    }

    @Override
    public FrontUser deleteUserById(String id) {
        FrontUser frontUser = baseMapper.selectById(id);
        if (frontUser != null) {
            if (baseMapper.deleteById(id) > 0)
                return frontUser;
            else
                return null;
        } else {
            return null;
        }
    }

    @Override
    public ResultObject getUserByOpenid(String openid) {

        QueryWrapper<FrontUser> wrapper = new QueryWrapper<>();
        wrapper.eq("wx_openid", openid);
        FrontUser frontUser = this.getOne(wrapper);
        if (frontUser == null) {
            return ResultObject.ok().message(ResultMessage.NO_SUCH_OBJECT);
        } else {
            return ResultObject.ok().putData(frontUser);
        }

    }

//    @Override
//    public UserBaseInfo getUserBaseInfoByToken(String token) {
//        String userId = JwtUtils.getUserIdByJwtToken(token);
//        FrontUser frontUser = baseMapper.selectById(userId);
//        if (frontUser == null)
//            return null;
//        UserBaseInfo userBaseInfo = new UserBaseInfo();
//        BeanUtils.copyProperties(frontUser, userBaseInfo);
//        userBaseInfo.setToken(token);
//        return userBaseInfo;
//    }

}
